import os
import sys
import json
import asyncio
import threading
from typing import Any, Dict, List, Optional
from pathlib import Path
from datetime import datetime
from loguru import logger


def ensure_directory(path: str) -> Path:
    """确保目录存在"""
    dir_path = Path(path)
    dir_path.mkdir(parents=True, exist_ok=True)
    return dir_path


def get_timestamp() -> str:
    """获取当前时间戳字符串"""
    return datetime.now().strftime("%Y%m%d_%H%M%S")


def safe_json_load(file_path: str, default: Any = None) -> Any:
    """安全加载JSON文件"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except Exception as e:
        logger.warning(f"加载JSON文件失败 {file_path}: {e}")
        return default


def safe_json_save(data: Any, file_path: str) -> bool:
    """安全保存JSON文件"""
    try:
        ensure_directory(Path(file_path).parent)
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2, default=str)
        return True
    except Exception as e:
        logger.error(f"保存JSON文件失败 {file_path}: {e}")
        return False


def format_duration(seconds: float) -> str:
    """格式化时长"""
    if seconds < 60:
        return f"{seconds:.1f}秒"
    elif seconds < 3600:
        minutes = int(seconds // 60)
        secs = seconds % 60
        return f"{minutes}分{secs:.1f}秒"
    else:
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = seconds % 60
        return f"{hours}小时{minutes}分{secs:.1f}秒"


def format_file_size(size_bytes: int) -> str:
    """格式化文件大小"""
    if size_bytes == 0:
        return "0B"
    
    size_names = ["B", "KB", "MB", "GB", "TB"]
    i = 0
    while size_bytes >= 1024 and i < len(size_names) - 1:
        size_bytes /= 1024.0
        i += 1
    
    return f"{size_bytes:.1f}{size_names[i]}"


def validate_url(url: str) -> bool:
    """验证URL格式"""
    import re
    pattern = re.compile(
        r'^https?://'  # http:// or https://
        r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|'  # domain...
        r'localhost|'  # localhost...
        r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'  # ...or ip
        r'(?::\d+)?'  # optional port
        r'(?:/?|[/?]\S+)$', re.IGNORECASE)
    return pattern.match(url) is not None


def run_async_in_thread(coro):
    """在新线程中运行异步函数"""
    import threading
    
    def run_in_thread():
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            return loop.run_until_complete(coro)
        finally:
            loop.close()
    
    thread = threading.Thread(target=run_in_thread)
    thread.daemon = True
    thread.start()
    return thread


def get_system_info() -> Dict[str, Any]:
    """获取系统信息"""
    import platform
    import psutil
    
    return {
        "platform": platform.system(),
        "platform_version": platform.version(),
        "architecture": platform.architecture()[0],
        "processor": platform.processor(),
        "python_version": platform.python_version(),
        "memory_total": psutil.virtual_memory().total,
        "memory_available": psutil.virtual_memory().available,
        "disk_total": psutil.disk_usage('/').total,
        "disk_free": psutil.disk_usage('/').free,
        "cpu_count": psutil.cpu_count(),
    }


def generate_selector_alternatives(selector: str) -> List[str]:
    """生成选择器的替代方案"""
    alternatives = [selector]
    
    # 如果是ID选择器，生成属性选择器
    if selector.startswith('#'):
        element_id = selector[1:]
        alternatives.append(f'[id="{element_id}"]')
        alternatives.append(f'*[id="{element_id}"]')
    
    # 如果是类选择器，生成属性选择器
    elif selector.startswith('.'):
        class_name = selector[1:]
        alternatives.append(f'[class*="{class_name}"]')
        alternatives.append(f'*[class*="{class_name}"]')
    
    # 添加更多通用选择器
    if ' ' in selector:  # 后代选择器
        parts = selector.split(' ')
        # 尝试只用最后一部分
        alternatives.append(parts[-1])
        # 尝试用直接子选择器
        alternatives.append(' > '.join(parts))
    
    return list(set(alternatives))  # 去重


def sanitize_filename(filename: str) -> str:
    """清理文件名，移除不安全字符"""
    import re
    
    # 移除或替换不安全字符
    filename = re.sub(r'[<>:"/\\|?*]', '_', filename)
    filename = re.sub(r'\s+', '_', filename)  # 空格替换为下划线
    filename = filename.strip('._')  # 移除开头结尾的点和下划线
    
    # 限制长度
    if len(filename) > 200:
        filename = filename[:200]
    
    return filename or "unnamed"


def deep_merge_dict(dict1: Dict, dict2: Dict) -> Dict:
    """深度合并字典"""
    result = dict1.copy()
    
    for key, value in dict2.items():
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = deep_merge_dict(result[key], value)
        else:
            result[key] = value
    
    return result


def truncate_text(text: str, max_length: int = 100, suffix: str = "...") -> str:
    """截断文本"""
    if len(text) <= max_length:
        return text
    return text[:max_length - len(suffix)] + suffix


def retry_on_exception(max_retries: int = 3, delay: float = 1.0, exceptions: tuple = (Exception,)):
    """重试装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            last_exception = None
            
            for attempt in range(max_retries + 1):
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    last_exception = e
                    if attempt < max_retries:
                        logger.warning(f"第{attempt + 1}次尝试失败: {e}, {delay}秒后重试...")
                        import time
                        time.sleep(delay)
                    else:
                        logger.error(f"重试{max_retries}次后仍然失败: {e}")
            
            raise last_exception
        
        return wrapper
    return decorator


class ThreadSafeCounter:
    """线程安全计数器"""
    
    def __init__(self, initial_value: int = 0):
        self._value = initial_value
        self._lock = threading.Lock()
    
    def increment(self) -> int:
        with self._lock:
            self._value += 1
            return self._value
    
    def decrement(self) -> int:
        with self._lock:
            self._value -= 1
            return self._value
    
    @property
    def value(self) -> int:
        with self._lock:
            return self._value


def setup_logging_config(level: str = "INFO", log_file: Optional[str] = None):
    """设置日志配置"""
    import sys
    from loguru import logger
    
    # 移除默认处理器
    logger.remove()
    
    # 添加控制台处理器
    logger.add(
        sys.stdout,
        level=level,
        format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | <level>{message}</level>",
        colorize=True
    )
    
    # 添加文件处理器（如果指定了日志文件）
    if log_file:
        ensure_directory(Path(log_file).parent)
        logger.add(
            log_file,
            level=level,
            format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} | {message}",
            rotation="10 MB",
            retention="10 days",
            compression="zip"
        )